package com.payment.system.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.payment.common.utils.*;
import com.payment.common.utils.http.HttpClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.payment.common.annotation.DataSource;
import com.payment.common.base.AjaxResult;
import com.payment.common.base.Const;
import com.payment.common.constant.UserConstants;
import com.payment.common.enums.DataSourceType;
import com.payment.common.enums.SystemConfigCode;
import com.payment.common.type.CreateStatusType;
import com.payment.common.type.LevelStatus;
import com.payment.common.type.PaymentOrderType;
import com.payment.common.type.SMSTemplateType;
import com.payment.common.utils.pay.EncryptUtil;
import com.payment.system.domain.AppVersion;
import com.payment.system.domain.BankOutlets;
import com.payment.system.domain.CardBin;
import com.payment.system.domain.CardType;
import com.payment.system.domain.IssBank;
import com.payment.system.domain.Merchant;
import com.payment.system.domain.MerchantDay;
import com.payment.system.domain.MerchantMonth;
import com.payment.system.domain.MerchantParent;
import com.payment.system.domain.MerchantUpgrade;
import com.payment.system.domain.MerchantWallet;
import com.payment.system.domain.PaymentOrder;
import com.payment.system.domain.ShoppingProduct;
import com.payment.system.domain.SystemConfig;
import com.payment.system.mapper.AppVersionMapper;
import com.payment.system.mapper.BankOutletsMapper;
import com.payment.system.mapper.CardBinMapper;
import com.payment.system.mapper.CardTypeMapper;
import com.payment.system.mapper.IssBankMapper;
import com.payment.system.mapper.MerchantDayMapper;
import com.payment.system.mapper.MerchantMapper;
import com.payment.system.mapper.MerchantMonthMapper;
import com.payment.system.mapper.MerchantParentMapper;
import com.payment.system.mapper.MerchantUpgradeMapper;
import com.payment.system.mapper.MerchantWalletMapper;
import com.payment.system.mapper.PaymentOrderMapper;
import com.payment.system.mapper.ShoppingProductMapper;
import com.payment.system.mapper.SystemConfigMapper;
import com.payment.system.service.IMerchantService;
import com.payment.system.util.GuangGuUtil;
import com.payment.system.vo.DayMonthVo;
import com.payment.system.vo.LoginVo;
import com.payment.system.vo.MerchantParentVo;
import com.payment.system.vo.MerchantVo;
import com.payment.system.vo.MyTeamVo;
import com.payment.system.vo.ParentMerchantVo;
import com.payment.system.vo.SettlementCardModifyVo;
import com.payment.system.vo.ShareVo;


/**
 * 商户 服务层实现
 *
 * @author payment
 * @date 2018-12-27
 */
@Service
public class MerchantServiceImpl implements IMerchantService {
    private static final Logger logger = LoggerFactory.getLogger(MerchantServiceImpl.class);

    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private BankOutletsMapper bankOutletsMapper;
    @Autowired
    private IssBankMapper issBankMapper;
    @Autowired
    private AppVersionMapper appVersionMapper;
    @Autowired
    private CardBinMapper binMapper;
    @Autowired
    private CardTypeMapper cardTypeMapper;
    @Autowired
    private MerchantUpgradeMapper upgradeMapper;
    @Autowired
    private MerchantParentMapper merchantParentMapper;
    @Autowired
    private MerchantDayMapper merchantDayMapper;
    @Autowired
    private MerchantMonthMapper merchantMonthMapper;
    @Autowired
    private SystemConfigMapper configMapper;
    @Autowired
    private ShoppingProductMapper shoppingProductMapper;
    @Autowired
    private PaymentOrderMapper paymentOrderMapper;
    @Autowired
    private MerchantWalletMapper merchantWalletMapper;

    /**
     * 查询商户信息
     * <p>
     * 商户ID
     *
     * @return 商户信息
     */
    @Override
    public Merchant selectMerchantById(String id) {
        return merchantMapper.selectMerchantById(id);
    }

    /**
     * 查询商户列表
     *
     * @param merchant 商户信息
     * @return 商户集合
     */
    @Override
    public List<Merchant> selectMerchantList(Merchant merchant) {
        List<Merchant> list = merchantMapper.selectMerchantList(merchant);
        if (list != null && list.size() > 0) {
            for (Merchant mer : list) {
                // 判断等级是否为O
                if (!mer.getLevel().equals(LevelStatus.ZERO.getCode())) {
                    // DES敏感信息脱敏
                    deDensity(mer);
                }
                Merchant parentMer = merchantMapper.selectByPhone(mer.getParentPhone());
                if (parentMer != null) {
                    mer.setParentMerchantName(parentMer.getMerchantCnName());
                    mer.setParentMerchantPhone(parentMer.getReservePhone());
                } else {
                    mer.setParentMerchantName("平台");
                }
            }
        }
        return list;
    }

    /**
     * 后台商户查看详情
     *
     * @return 商户信息
     */
    @Override
    public Merchant selectMerchantByIdDeDensity(String id) {
        Merchant mer = merchantMapper.selectMerchantById(id);
        if (!mer.getLevel().equals(LevelStatus.ZERO.getCode())) {
            deDensity(mer);
        }
        return mer;
    }


    /**
     * 新增商户
     *
     * @param merchant 商户信息
     * @return 结果
     */
    @Override
    public int insertMerchant(Merchant merchant) {
        return merchantMapper.insertMerchant(merchant);
    }

    /**
     * 修改商户
     *
     * @param merchant 商户信息
     * @return 结果
     */
    @Override
    public int updateMerchant(Merchant merchant) {
        return merchantMapper.updateMerchant(merchant);
    }

    /**
     * 启用或禁用商户
     *
     * @param id
     * @return
     */
    @Override
    public AjaxResult updateUseStatusById(String id) {
        if (StringUtils.isEmpty(id)) {
            return AjaxResult.error("缺失参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(id);
        if (merchant == null) {
            return AjaxResult.error("暂无此商户");
        }
        String status = "";
        if ("10B".equals(merchant.getUserStatus())) {
            status = "10A";
        } else {
            status = "10B";
        }
        int result = merchantMapper.updateUseStatusById(id, status);
        if (result > 0) {
            return AjaxResult.success("修改商户状态成功");
        }
        return AjaxResult.error("修改商户状态失败，请稍后再试！");

    }


    /**
     * app用户登陆
     *
     * @param loginName  账号
     * @param password   密码
     * @param versionNo  版本号
     * @param systemType 系统类型 【IOS/Android】 0 ios 1安卓
     * @return
     */
    @Override
    public AjaxResult login(String loginName, String password, String versionNo, String systemType, String isOnline) {
        if (StringUtils.isEmpty(versionNo) || StringUtils.isEmpty(systemType)) {
            return AjaxResult.error(1, "版本号或系统类型不能为空！");
        }
        if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password)) {
            return AjaxResult.error(2, "账号或密码不能为空！");
        }
        if (StringUtils.isEmpty(isOnline)) {
            isOnline = "";
        }
        if (systemType.equals("0") && !versionNo.equals("1.0.2") || systemType.equals("1")) {
            // 判断当前版本号
            AppVersion version = appVersionMapper.selectAppVersionByVersionNo(versionNo, systemType);
            // 获取最新版本号
            AppVersion versionNow = appVersionMapper.selectAppVersionByNow(systemType);
            if (version == null) {
                return AjaxResult.error(3, "当前版本号不存在！");
            }
            if (!version.getVersionNo().equals(versionNow.getVersionNo())) {
                return AjaxResult.error(4, "当前版本号不是最新版本，请升级后再登陆！");
            }
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(loginName);
        if (merchant == null) {
            return AjaxResult.error(5, "该用户不存在！");
        }
        if (("10B").equals(merchant.getUserStatus())) {
            return AjaxResult.error(5, "用户已禁用！");
        }
        LoginVo mer = merchantMapper.selectMerchantByPhoneAndPwd(loginName, Md5Utils.encrypt2MD5(password));
        if (mer == null) {
            return AjaxResult.error(6, "账号密码不正确！");
        }
        mer.setAuthorizationParent(merchant.getAuthorizationParent());
        SystemConfig systemConfig = configMapper.selectSystemConfigByConfigCode(SystemConfigCode.IS_ONLINE.getCode());
        // 苹果0 1安卓
        JSONObject isOnlineJson = JSONObject.parseObject(systemConfig.getConfigValue());
        if (isOnline.equals("0")) {
            mer.setIsOnline(isOnlineJson.getString("ios"));
        } else if (isOnline.equals("1")) {
            mer.setIsOnline(isOnlineJson.getString("android"));
        } else {
            return AjaxResult.successAndData("用户登陆成功", mer);
        }
        // TODO 环信
        Map<String, String> result = TokenUtils.getUserName(loginName);
        System.out.println(result.toString());
        if (StringUtils.isNull(result.get("response"))) {
            String passwords = "123456";
            TokenUtils.getAccessUsers(loginName, passwords);
        }
        return AjaxResult.successAndData("用户登陆成功", mer);
    }

    /**
     * app商户注册
     *
     * @param phone       登录注册手机号
     * @param password    登录密码
     * @param passwordNow 确认密码
     * @param code        手机验证码
     * @param parentPhone 推荐人手机号
     * @return
     */
    @Override
    public AjaxResult register(String phone, String password, String passwordNow, String code, String parentPhone) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordNow)
                || StringUtils.isEmpty(code) || StringUtils.isEmpty(parentPhone)) {
            return AjaxResult.error(1, "缺失参数！");
        }
        if (password != null && password.length() < 6) {
            return AjaxResult.error(2, "密码在6到14位！");
        }
        if (password.length() > 14) {
            return AjaxResult.error(2, "密码在6到14位！");
        }
        if (!SendMessageUtils.isPhone(phone)) {
            return AjaxResult.error(2, "请上传正确格式的手机号！");
        }
        if (!password.equals(passwordNow)) {
            return AjaxResult.error(3, "2次密码不匹配！");
        }
        if (StringUtils.isEmpty(code)) {
            return AjaxResult.error(4, "验证码不能为空！");
        }
        if (StringUtils.isEmpty(parentPhone)) {
            return AjaxResult.error(5, "推荐人手机号不能为空！");
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(phone);
        if (merchant != null) {
            RedisPoolUtil.del(phone + Const.TIME);
            return AjaxResult.error(8, "该手机号已注册！");
        }
        String redisCode = RedisPoolUtil.get(phone + Const.TIME);
        if (StringUtils.isEmpty(redisCode)) {
            return AjaxResult.error(6, "未获取验证码！");
        }
        if (!code.equals(redisCode)) {
            return AjaxResult.error(7, "验证码不正确！");
        }
        Merchant parent = null;
        Merchant user = new Merchant();
        if (!"123".equals(parentPhone)) {
            parent = merchantMapper.selectMerchantByPhone(parentPhone);
            if (parent == null) {
                return AjaxResult.error(9, "推荐人不存在！");
            }
        }
        // 用户id
        user.setId(StringUtils.randomUUID());
        // 商户编号
        user.setMerchantNo(StringUtils.getMerchantNo(phone));
        // 用户姓名未实名默认手机号
        user.setMerchantCnName(phone);
        // 注册登录手机号
        user.setPhone(phone);
        // 登录密码
        user.setPassword(Md5Utils.encrypt2MD5(password));
        // 推荐人手机号
        user.setParentPhone(parentPhone);
        // 用户预留手机号默认注册手机号
        user.setReservePhone(phone);
        // 用户状态可用
        user.setUserStatus(CreateStatusType.CREATE.getCode());
        // 默认注册是0级未实名
        user.setLevel(0);
        // 待实名状态
        user.setRealNameStatus("10A");
        user.setCreateTime(new Date());
        merchantMapper.insertMerchant(user);
        MerchantUpgrade up = new MerchantUpgrade();
        up.setId(StringUtils.randomUUID());
        up.setMerchantId(user.getId());
        up.setPhone(user.getPhone());
        up.setLevel(0);
        //10A=手动升级,10B=自动升级
        up.setType("10B");
        up.setCreateTime(new Date());
        up.setMerchantName(user.getMerchantCnName());
        upgradeMapper.insertMerchantUpgrade(up);
        MerchantWallet mw = new MerchantWallet();
        mw.setId(StringUtils.randomUUID());
        mw.setMerchantId(user.getId());
        merchantWalletMapper.insertMerchantWallet(mw);
        /*** 新开线程整理客户关系 **/
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        singleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                // do something
                String phones = parentPhone;
                int i = 1;
                while (true) {
                    Merchant u = merchantMapper.selectByPhone(phones);
                    if (u == null) {
                        break;
                    }
                    MerchantParent merchantParent = new MerchantParent();
                    merchantParent.setMerchantPhone(phone);
                    merchantParent.setParentPhone(u.getPhone());
                    merchantParent.setIntervals(i);
                    merchantParentMapper.insertMerchantParent(merchantParent);
                    i++;
                    phones = u.getParentPhone();
                }
                singleThreadExecutor.shutdown();
            }
        });
        RedisPoolUtil.del(phone + Const.TIME);
        return AjaxResult.success("商户注册成功！");
    }


    /**
     * app端用户忘记密码
     *
     * @param phone       手机号
     * @param password    密码
     * @param passwordNow 确认密码
     * @param code        验证码
     * @return
     */
    @Override
    public AjaxResult restPasswordByCode(String phone, String password, String passwordNow, String code) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordNow)
                || StringUtils.isEmpty(code)) {
            return AjaxResult.error(1, "用户修改密码失败:缺失参数！");
        }
        if (!StringUtils.equals(password, passwordNow)) {
            return AjaxResult.error(2, "用户修改密码失败:2次密码不匹配！");
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(phone);
        if (merchant == null) {
            return AjaxResult.error(3, "用户修改密码失败:该用户不存在！");
        }
        String redisCode = RedisPoolUtil.get(phone + Const.TIME);

        if (!StringUtils.equals(redisCode, code)) {
            return AjaxResult.error(4, "用户修改密码失败:验证码错误！");
        }
        try {
            int rowCount = merchantMapper.updateMerchantByPhone(phone, Md5Utils.encrypt2MD5(password));
            if (rowCount > 0) {
                RedisPoolUtil.del(phone + Const.TIME);
                return AjaxResult.success("用户修改密码成功！");
            }
            RedisPoolUtil.del(phone + Const.TIME);
            return AjaxResult.error(5, "用户修改密码失败！");
        } catch (Exception e) {
            RedisPoolUtil.del(phone + Const.TIME);
            logger.error("app用户修改密码失败{}", e);
            return AjaxResult.error("用户修改密码失败,请联系客服咨询");
        }
    }

    @Override
    public AjaxResult updatePasswordByMerchantId(String merchantId, String password, String passwordNow) {
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordNow)) {
            return AjaxResult.error(1, "修改密码失败：缺失参数！");
        }
        if (!StringUtils.equals(password, passwordNow)) {
            return AjaxResult.error(2, "修改密码失败：2次密码输入不一致！");
        }
        if (merchant == null) {
            return AjaxResult.error(3, "修改密码失败：暂无该用户信息！");
        }
        try {
            merchantMapper.updatePasswordByMerchantId(merchantId, Md5Utils.encrypt2MD5(password));
            return AjaxResult.success("修改密码成功！");
        } catch (Exception e) {
            logger.error("用户认证失败！请联系客服咨询{}", e);
            return AjaxResult.error("用户认证失败！请联系客服咨询");

        }

    }


    /**
     * 验证码发送
     */
    @Override
    public AjaxResult getMessageCode(String phone) {
        logger.info("发送验证码开始");
        if (!SendMessageUtils.isPhone(phone)) {
            return AjaxResult.error(1, "发送验证码失败：手机号格式不正确！");
        }
        if (!phone.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN)) {
            return AjaxResult.error(1, "发送验证码失败：手机号格式不正确！");
        }
        //判断用户发验证码
        int sendStatus = this.checkSendShortMessage(phone);
        if (sendStatus == Const.SendMessageEnum.DISABLERESEND.getCode()) {
            return AjaxResult.error(3, "切勿重复发送验证码！");
        }
        try {
            //验证码
            String randomVcode = SendMessageUtils.createRandomVcode();
            logger.info("发送验证码类型：" + SMSTemplateType.SENDOUT.getCode() + "  手机号：==" + phone);
            Map<String, String> params = new HashMap<>(16);
            //手机号
            params.put("user_phone", phone);
            //发送内容
            params.put("content", randomVcode);
            //有效期(分钟)
            String validity = String.valueOf(Const.RedisCacheExtime.REDIS_MESSAGE_CODE_VALIDITY);
            params.put("validity", validity);
            //业务类型 SEND_OUT:发送验证 NOTICE:短信通知
            params.put("sendType", SMSTemplateType.SENDOUT.getCode());
            //上送短信
            JSONObject gg = GuangGuUtil.smsPackage(params);
            String retCode = gg.getString("ret_code");
            String resCode = gg.getString("res_code");
            if (("SUCCESS").equals(retCode)) {
                if (("YQB000000").equals(resCode)) {
                    //有效期五分钟存redis验证码
                    RedisPoolUtil.setex(phone + Const.TIME, randomVcode, Const.RedisCacheExtime.REDIS_MESSAGE_CODE_EXTIME);
                    return AjaxResult.success("发送验证码成功！");
                } else {
                    return AjaxResult.error(gg.getString("res_msg"));
                }
            }
        } catch (Exception e) {
            logger.error("发送验证码失败！请联系客服咨询.{}", e);
            return AjaxResult.error("发送验证码失败！请联系客服咨询");
        }
        return AjaxResult.error("发送验证码失败！请联系客服咨询");
    }


    /**
     * app商户实名认证第二步保存用户信息
     *
     * @param merchantId   用户ID
     * @param name         姓名
     * @param idCard       身份证号
     * @param phone        手机号
     * @param bankAccount  卡号
     * @param bankProvince 开户行省
     * @param bankCity     开户行市
     * @return
     */
    @Override
    public AjaxResult authenticationTwo(String merchantId, String name, String idCard, String phone, String bankAccount,
                                        String bankProvince, String bankCity) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(name) || StringUtils.isEmpty(idCard)
                || StringUtils.isEmpty(phone) || StringUtils.isEmpty(bankAccount) || StringUtils.isEmpty(bankCity)
                || StringUtils.isEmpty(bankProvince)) {
            return AjaxResult.error(1, "实名认证失败：缺失参数！");
        }
        String redisKey = "lock:RealName:" + merchantId;
        // 查询商户信息
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error(2, "实名认证失败：该用户不存在！");
        }
        int idnumber = merchantMapper.selectCountByCardNumber(idCard.trim());
        if (idnumber > 0) {
            return AjaxResult.error(2, "该身份证号已经注册，切勿重复注册！如有疑问请联系客服 4008083305");
        }
        String suo = RedisPoolUtil.get(redisKey);
        if (suo == null || !suo.equals("1")) {// 判断是不是重复提交
            RedisPoolUtil.set(redisKey, "1");// 提交加锁
            // 查询卡bin信息
            CardBin cb = binMapper.selectCardBinByBankNo(bankAccount.trim().length(), bankAccount.trim());
            if (cb == null) {
                RedisPoolUtil.del(redisKey);// 完成注册取消锁
                return AjaxResult.error(2, "该银行卡未识别卡bin信息，请联系客服！");
            }
            // 验证是否贷记卡（信用卡）
            CardType cardType = cardTypeMapper.selectCardTypeByTypeId(cb.getCardTypeId(), 1);
            if (cardType == null) {
                RedisPoolUtil.del(redisKey);// 完成注册取消锁
                return AjaxResult.error(2, "该银行卡不是借记卡，请联系客服！");
            }
            // 获取银行信息
            IssBank issBank = issBankMapper.selectIssBankById(cb.getBankId());
            if (null == issBank) {
                RedisPoolUtil.del(redisKey);// 完成注册取消锁
                return AjaxResult.error(2, "未获取到所属银行信息，请联系客服！");
            }
            // 预留手机号
            merchant.setReservePhone(phone);
            // 开户省
            merchant.setBankProvince(bankProvince);
            // 开户市
            merchant.setBankCity(bankCity);
            // 开户县区
            merchant.setBankDistrict("");
            // 开户人姓名
            merchant.setMerchantCnName(name);
            // 身份证号
            merchant.setIdCardNumber(idCard);
            // 卡号
            merchant.setBankAccount(bankAccount);
            // 开户行银行名称
            merchant.setBankName(issBank.getShortCnName());
            merchant.setBankAbbr(issBank.getIssuerCode());
            // 实名审核时间
            merchant.setRealNameTime(new Date());
            // 银行代码
            merchant.setBankCode(issBank.getBankCode());
            // 等级设为一级
            if (merchant.getLevel() == null || merchant.getLevel() <= 1) {
                merchant.setLevel(LevelStatus.ONE.getCode());
            }
            // 查询联行号
            BankOutlets outlets = bankOutletsMapper.selectBankOutletsByName(issBank.getBankName());
            if (outlets != null) {
                // 银行联行号
                merchant.setBankDot(outlets.getCnaps());
            } else {
                merchant.setBankDot("000000000000");
            }
            try {
                // 请求流水号
                merchant.setSeriaNo(StringUtils.createNum());
                /** 调用三方的四要素校验 */
                JSONObject json = GuangGuUtil.VerificationOfFourElements(merchant);
                if (StringUtils.isNotNull(json)) {
                    if ("SUCCESS".equals(json.getString("ret_code"))) {
                        if ("YQB000000".equals(json.getString("res_code"))) {
                            // 认证备注
                            merchant.setRealNameRemarks("自动审核通过");
                            /** 用户签约光谷 */
                            JSONObject jsonObject = GuangGuUtil.userSign(merchant);
                            if ("SUCCESS".equals(json.getString("ret_code"))) {
                                if ("YQB000000".equals(jsonObject.getString("res_code"))) {
                                    // 用户签约返回的userId
                                    String userId = jsonObject.getString("user_id");
                                    // TODO 添加签约用户id
                                    merchant.setAcqMerchantNo(userId);
                                    // 实名认证是否通过  10B老用户状态   10E用户成功
                                    merchant.setRealNameStatus("10E");
                                    // 修改用户信息
                                    // 给一个月试用会员费率
                                    Calendar day = Calendar.getInstance();
                                    day.setTime(new Date());
                                    day.add(Calendar.MONTH, 1);
                                    merchant.setRechargeTime(day.getTime());
                                    merchantMapper.updateMerchant(merchant);
                                    RedisPoolUtil.del(merchantId);// 完成注册取消锁
                                    MerchantUpgrade up = new MerchantUpgrade();
                                    up.setId(StringUtils.randomUUID());
                                    up.setMerchantId(merchant.getId());
                                    up.setPhone(merchant.getPhone());
                                    up.setCreateTime(new Date());
                                    // 10A=手动升级,10B=自动升级
                                    up.setType("10B");
                                    up.setMerchantName(merchant.getMerchantCnName());
                                    List<PaymentOrder> orderList = paymentOrderMapper
                                            .selectPaymentOrderListByMerchantIdAndStatus(merchantId, 1,
                                                    PaymentOrderType.SIX.getCode());
                                    if (orderList != null && orderList.size() > 0) {
                                        up.setLevel(merchant.getLevel());
                                    } else {
                                        up.setLevel(1);
                                    }
                                    upgradeMapper.insertMerchantUpgrade(up);
                                    // 查询上级普通用户推10个普通用户可升级，推一个给一个月试用期
                                    Merchant pmer = merchantMapper.selectByPhone(merchant.getParentPhone());
                                    if (pmer != null && pmer.getLevel().equals(1)) {
                                        Integer num = merchantMapper.selectZTcountByLevel(merchant.getParentPhone(), 1);
                                        if (num >= 10) {
                                            Merchant newPmer = new Merchant();
                                            newPmer.setId(pmer.getId());
                                            newPmer.setLevel(2);
                                            newPmer.setIsCompany("10E");
                                            merchantMapper.updateMerchant(merchant);
                                            MerchantUpgrade upp = new MerchantUpgrade();
                                            upp.setId(StringUtils.randomUUID());
                                            upp.setMerchantId(newPmer.getId());
                                            upp.setPhone(newPmer.getPhone());
                                            upp.setCreateTime(new Date());
                                            upp.setType("10B");
                                            upp.setMerchantName(newPmer.getMerchantCnName());
                                            upp.setLevel(2);
                                            upgradeMapper.insertMerchantUpgrade(upp);
                                        } else {
                                            Calendar pday = Calendar.getInstance();
                                            pday.setTime(pmer.getRealNameTime());
                                            pday.add(Calendar.MONTH, num);
                                            Merchant newPmer = new Merchant();
                                            newPmer.setId(pmer.getId());
                                            // 试用到期时间
                                            newPmer.setRechargeTime(pday.getTime());
                                            merchantMapper.updateMerchant(merchant);
                                        }
                                    }
                                    return AjaxResult.success("实名认证成功!");
                                } else {
                                    // 完成注册取消锁
                                    RedisPoolUtil.del(redisKey);
                                    // 拿用户签约返回信息jsonObject
                                    return AjaxResult.error(4, jsonObject.getString("res_msg"));
                                }
                            }
                        } else {
                            Merchant merchantNo = merchantMapper.selectMerchantById(merchantId);
                            // 认证备注
                            merchantNo.setRealNameRemarks(json.getString("res_msg"));
                            // 实名认证是否通过
                            merchantNo.setRealNameStatus("10C");
                            // 修改用户信息
                            merchantMapper.updateMerchant(merchantNo);
                            // 完成注册取消锁
                            RedisPoolUtil.del(redisKey);
                            return AjaxResult.error(4, json.getString("res_msg"));
                        }
                    }
                } else {
                    RedisPoolUtil.del(redisKey);// 完成注册取消锁
                    return AjaxResult.error("实名认证失败！请联系客服咨询");
                }
            } catch (Exception e) {
                RedisPoolUtil.del(redisKey);// 完成注册取消锁
                logger.error("实名认证异常", e);
                return AjaxResult.error("实名认证失败！请联系客服咨询");
            }
        } else {
            return AjaxResult.error(5, "请勿重复提交");
        }
        RedisPoolUtil.del(redisKey);// 完成注册取消锁
        return AjaxResult.error("实名认证失败！请联系客服咨询");
    }


    // app端设置交易密码
    @Override
    public AjaxResult savePayPassword(String merchantId, String password, String passwordNow, String code) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordNow)
                || StringUtils.isEmpty(code)) {
            return AjaxResult.error(1, "设置交易密码失败：缺失参数！");
        }
        AjaxResult val = this.validatePwd(merchantId, password, passwordNow);

        if (Integer.parseInt(String.valueOf(val.get("code"))) != 0) {
            return val;
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        //获取登录手机号的redis
        String redisCode = RedisPoolUtil.get(merchant.getPhone() + Const.TIME);
        if (!StringUtils.equals(redisCode, code)) {
            return AjaxResult.error(2, "用户修改密码失败:验证码错误！");
        }
        merchantMapper.updatePayPassword(merchantId, Md5Utils.encrypt2MD5(password));
        RedisPoolUtil.del(merchant.getPhone() + Const.TIME);
        return AjaxResult.success("设置交易密码成功");
    }

    // app修改交易密码
    @Override
    public AjaxResult updatePayPassword(String merchantId, String passwordOld, String password, String passwordNow) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordNow)
                || StringUtils.isEmpty(passwordOld)) {
            return AjaxResult.error(1, "修改交易密码失败：缺失参数！");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        AjaxResult val = this.validatePwd(merchantId, password, passwordNow);
        if (Integer.parseInt(String.valueOf(val.get("code"))) != 0) {
            return val;
        }
        if (!StringUtils.equals(Md5Utils.encrypt2MD5(passwordOld), merchant.getPaymentPwd())) {
            return AjaxResult.error(4, "修改交易密码失败：旧密码不正确！");
        }
        merchantMapper.updatePayPassword(merchantId, Md5Utils.encrypt2MD5(password));
        return AjaxResult.success("修改交易密码成功");

    }

    // 忘记交易密码
    @Override
    public AjaxResult restPayPasswordByCode(String merchantId, String phone, String password, String passwordNow,
                                            String code) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(passwordNow) || StringUtils.isEmpty(code)) {
            return AjaxResult.error(1, "用户修改支付密码失败:缺失参数！");
        }
        if (!StringUtils.equals(password, passwordNow)) {
            return AjaxResult.error(2, "用户修改支付密码失败:2次密码不匹配！");
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(phone);
        if (merchant == null) {
            return AjaxResult.error(3, "用户修改支付密码失败:该用户不存在！");
        }
        String redisCode = RedisPoolUtil.get(phone + Const.TIME);
        if (!StringUtils.equals(redisCode, code)) {
            return AjaxResult.error(4, "用户修改支付密码失败:验证码错误！");
        }
        try {
            int rowCount = merchantMapper.updatePayPassword(merchantId, Md5Utils.encrypt2MD5(password));
            if (rowCount > 0) {
                RedisPoolUtil.del(merchant.getPhone() + Const.TIME);
                return AjaxResult.success("用户修改支付密码成功！");
            }
            return AjaxResult.error(5, "用户修改支付密码失败！");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("用户修改支付密码失败！请联系客服咨询=" + e.toString());
            return AjaxResult.error("用户修改支付密码失败！请联系客服咨询");

        }
    }

    /**
     * app获取直推客户信息
     *
     * @param merchantPhone 手机号
     * @param pageNum       页数
     * @param pageSize      每页条数
     * @return
     */
    @Override
    public AjaxResult directCustomerList(String merchantPhone, Integer pageNum, Integer pageSize) {
        if (StringUtils.isEmpty(merchantPhone) || pageNum == null || pageSize == null) {
            return AjaxResult.error(1, "获取联系人失败：缺失参数");
        }
        Merchant merchant = merchantMapper.selectByPhone(merchantPhone);
        if (StringUtils.isNull(merchant)) {
            return AjaxResult.error("无效商户");
        }
        List<MerchantVo> list = merchantMapper.selectDirectCustomerList(merchantPhone, pageNum * pageSize, pageSize);
        return AjaxResult.successAndData("获取联系人成功", list);
    }


    protected AjaxResult validatePwd(String merchantId, String password, String passwordNow) {
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (!StringUtils.equals(password, passwordNow)) {
            return AjaxResult.error(2, "设置交易密码失败：2次密码不一致！");
        }
        if (password.length() != 6) {
            return AjaxResult.error(3, "设置交易密码失败：请输入6位支付密码！");
        }

        if (merchant == null) {
            return AjaxResult.error(1, "设置交易密码失败：该用户不存在！");
        }
        return AjaxResult.success();
    }

    /**
     * 判断手机号是否重复发送短信
     *
     * @param phone
     * @return
     */
    private int checkSendShortMessage(String phone) {
        // 判断redis中是否存在该手机号
        String code = RedisPoolUtil.get(phone + Const.TIME);
        // 如果手机号在redis中不存在，说明可以获取验证码
        if (StringUtils.isEmpty(code)) {
            return Const.SendMessageEnum.FIRSTSEND.getCode();
        }
        return Const.SendMessageEnum.DISABLERESEND.getCode();
    }

    // 自动补全商户名称
    @Override
    public List<String> selectNameByAutosearch(String name) {
        return merchantMapper.selectNameByAutosearch(name);
    }

    @DataSource(DataSourceType.SLAVE)
    @Override
    public Merchant selectByPhone(String phone) {
        return merchantMapper.selectByPhone(phone);
    }

    // 校验支付密码
    @Override
    public AjaxResult verificationPayPassword(String merchantId, String payPassword) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(payPassword)) {
            return AjaxResult.error(1, "缺失参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error(2, "该用户不存在");
        }
        if (!StringUtils.equals(merchant.getPaymentPwd(), Md5Utils.encrypt2MD5(payPassword))) {
            return AjaxResult.error(3, "原支付密码不正确");
        }
        return AjaxResult.success("支付密码检验成功");
    }

    // 返回：总收益， 可提现 ，冻结 ，已提现
    @Override
    public AjaxResult selectMoneyTotalByMerchantId(String merchantId) {
        if (StringUtils.isEmpty(merchantId)) {
            return AjaxResult.error(1, "缺失参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        MerchantWallet merchantWallet = merchantWalletMapper.selectMerchantWalletByMerId(merchantId);
        if (merchantWallet == null || merchant == null) {
            return AjaxResult.error(2, "该用户不存在");
        }
        Map<String, Object> map = new HashMap<>(16);
        //查询 提现
        map.put("haveWithdrawal", merchantWallet.getCashIntegral());// 已提现
        //查询资金变动表 总收益
        map.put("totalRevenue", merchantWallet.getTotalMoney());// 总收益:
        map.put("canWithdrawal", merchantWallet.getBalanceMoney());// 可提现
        //查询账户的储蓄卡信息
        //储蓄卡卡号
        map.put("bankAccount", merchant.getBankAccount());
        //持卡人手机号
        map.put("linkPhone", merchant.getReservePhone());
        //储蓄卡名称
        map.put("bankDetail", merchant.getBankName());
        //持卡人姓名
        map.put("bankAccountName", merchant.getMerchantCnName());
        //根据银行代码查询银行卡信息
        IssBank issBank = issBankMapper.selectIssBankByCode(merchant.getBankCode());
        //储蓄卡图片
        if (!StringUtils.isEmpty(issBank.getDepositCardImg())) {
            map.put("depositCardImg", issBank.getDepositCardImg());
        } else {
            map.put("depositCardImg", "");
        }
        // 银行卡logo图片
        if (!StringUtils.isEmpty(issBank.getBankLogoImg())) {
            map.put("bankLogoImg", issBank.getBankLogoImg());
        } else {
            map.put("bankLogoImg", "");
        }

        return AjaxResult.successAndData("获取账户信息成功", map);
    }

    /**
     * 更换储蓄卡
     *
     * @param merchantId  商户id
     * @param bankAccount 储蓄卡号
     * @param linkPhone   预留手机号
     * @param payPwd      交易密码
     * @return
     * @throws Exception
     */
    @Override
    public AjaxResult replaceSettlementCard(String merchantId, String bankAccount,
                                            String linkPhone, String payPwd, String bankProvince, String bankCity) throws Exception {

        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(payPwd) || StringUtils.isEmpty(bankAccount) || StringUtils.isEmpty(linkPhone)) {
            return AjaxResult.error("信息无效，缺失参数");
        }
        Merchant m = merchantMapper.selectMerchantById(merchantId);
        if (StringUtils.isNull(m)) {
            return AjaxResult.error("信息无效，用户不存在");
        }
        if (payPwd != null && Md5Utils.encrypt2MD5(payPwd).equals(m.getPaymentPwd())) {
            //银行卡号
            m.setBankAccount(bankAccount);
            //预留手机号
            m.setReservePhone(linkPhone);
            //请求流水号
            m.setSeriaNo(StringUtils.createNum());
            JSONObject j = GuangGuUtil.VerificationOfFourElements(m);
            if (StringUtils.isNull(j)) {
                return AjaxResult.error("四要素鉴权失败，请联系客服咨询");
            }
            if ("SUCCESS".equals(j.getString("ret_code"))) {
                if ("YQB000000".equals(j.getString("res_code"))) {
                    // 查询卡bin信息
                    CardBin cb = binMapper.selectCardBinByBankNo(m.getBankAccount().length(), m.getBankAccount());
                    // 验证是否属于识别的银行卡
                    if (null != cb) {
                        // 验证是否贷记卡（信用卡）
                        CardType cardType = cardTypeMapper.selectCardTypeByTypeId(cb.getCardTypeId(), 1);
                        if (cardType == null) {
                            return AjaxResult.error(2, "该银行卡不是借记卡");
                        }
                        // 获取银行信息
                        IssBank issBank = issBankMapper.selectIssBankById(cb.getBankId());
                        if (null == issBank) {
                            return AjaxResult.error(2, "未获取到所属银行信息");
                        }
                        // 查询联行号
                        BankOutlets outlets = bankOutletsMapper.selectBankOutletsByName(issBank.getBankName());
                        if (outlets != null) {
                            m.setBankDot(outlets.getCnaps());
                        } else {
                            m.setBankDot("000000000000");
                        }
                        //银行简称
                        m.setBankName(issBank.getShortCnName());
                        //银行代码
                        m.setBankCode(issBank.getBankCode());
                        m.setBankProvince(bankProvince);
                        m.setBankCity(bankCity);
                        //调用光谷结算卡变更
                        SettlementCardModifyVo cardModifyVo = new SettlementCardModifyVo();
                        cardModifyVo.setUserId(m.getAcqMerchantNo());
                        cardModifyVo.setUserName(m.getMerchantCnName());
                        cardModifyVo.setUserdIdCard(m.getIdCardNumber());
                        cardModifyVo.setBankCardNo(m.getBankAccount());
                        cardModifyVo.setBankName(m.getBankName());
                        cardModifyVo.setBankCode(m.getBankCode());
                        cardModifyVo.setBankAbbr(m.getBankAbbr());
                        cardModifyVo.setBankChannelNo(m.getBankDot());
                        cardModifyVo.setBankProvince(m.getBankProvince());
                        cardModifyVo.setBankCity(m.getBankCity());
                        cardModifyVo.setBankCardPhone(m.getReservePhone());
                        JSONObject jsonObject = GuangGuUtil.settlementCardModify(cardModifyVo);
                        if (jsonObject != null && "YQB000000".equals(jsonObject.getString("res_code")) && "1".equals(jsonObject.getString("status"))) {
                            merchantMapper.updateMerchant(m);
                            return AjaxResult.success("成功");
                        } else {
                            return AjaxResult.error(jsonObject == null ? "结算卡变更失败" : jsonObject.getString("res_msg"));
                        }
                    } else {
                        return AjaxResult.error("系统检测不到卡Bin信息,请联系客服咨询");
                    }
                } else {
                    return AjaxResult.error(j.getString("res_msg"));
                }
            } else {
                return AjaxResult.error("修改失败,请联系客服咨询");
            }
        }
        return AjaxResult.error("支付密码错误");
    }


    /**
     * 分享界面 查询商户统计记录(我的团队,我的收益，我的交易 )
     *
     * @param merchantId 用户ID
     * @return
     */
    @Override
    public AjaxResult selectMerchantStatisticRecordByMerchantId(String merchantId) {
        if (StringUtils.isEmpty(merchantId)) {
            return AjaxResult.error("获取信息失败，请重试！");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error("获取信息失败，请重试！");
        }
        ShareVo shareVo = new ShareVo();
        List<MerchantParentVo> ml = merchantMapper.selectAllTeamByParentphone(merchant.getPhone());
        List<MerchantParentVo> newMl = merchantMapper.selectNewTeamByParentphone(merchant.getPhone(),
                DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + " 00:00:00", DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + " 23:59:59");
        int ordinaryTotal = 0;//团队普通用户
        int vipTotal = 0;// 团队vip
        int partnerTotal = 0;// 团队核心合伙人
        int newOrdinaryTotal = 0;//新注册普通用户
        int newVipTotal = 0;//新注册
        int newPartnerTotal = 0;//新注册
        for (MerchantParentVo merchantParentVo : ml) {
            if (merchantParentVo.getLevel().equals(1)) {
                ordinaryTotal++;
            }
            if (merchantParentVo.getLevel().equals(2)) {
                vipTotal++;
            }
            if (merchantParentVo.getLevel().equals(6)) {
                partnerTotal++;
            }
        }
        for (MerchantParentVo merchantParentVo : newMl) {
            if (merchantParentVo.getLevel().equals(1)) {
                newOrdinaryTotal++;
            }
            if (merchantParentVo.getLevel().equals(2)) {
                newVipTotal++;
            }
            if (merchantParentVo.getLevel().equals(6)) {
                newPartnerTotal++;
            }
        }
        shareVo.setTeamTotal(ml.size());
        shareVo.setOrdinaryTotal(ordinaryTotal);
        shareVo.setVipTotal(vipTotal);
        shareVo.setPartnerTotal(partnerTotal);

        shareVo.setNewTotal(newMl.size());
        shareVo.setNewOrdinaryTotal(newOrdinaryTotal);
        shareVo.setNewVipTotal(newVipTotal);
        shareVo.setNewPartnerTotal(newPartnerTotal);
        //查询日统计表 （昨日收益）
        MerchantDay day = merchantDayMapper.selectMerchantByYesterdayProfit(merchant.getId());
        MerchantWallet merchantWallet = merchantWalletMapper.selectMerchantWalletByMerId(merchantId);
        shareVo.setYesterdayProfit(day == null ? new BigDecimal("0.000") : day.getProfit());
        //今日收益
        shareVo.setTodayProfit(merchantWallet.getProfit().compareTo(new BigDecimal(0)) >= 0 ? merchantWallet.getProfit() : new BigDecimal("0.000"));
        //本月收益
        shareVo.setThisMonthProfit(merchantWallet.getProfitMoth());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MONTH, -1);
        Date m = c.getTime();
        String mon = format.format(m);
        //查询月统计表（上月收益）
        MerchantMonth month = merchantMonthMapper.selectMerchantMonthByMerchantIdAndTime(merchant.getId(), mon + "-01 00:00:00");
        shareVo.setLastMonthProfit(month == null ? new BigDecimal("0.000") : month.getProfit());
        //日收款
        shareVo.setDaySk(merchantWallet.getSkDay());
        //月收款
        shareVo.setMonthSk(merchantWallet.getSkMonth());
        //日还款
        shareVo.setDayHk(merchantWallet.getHkDay());
        //月还款
        shareVo.setMonthHk(merchantWallet.getHkMonth());
        return AjaxResult.successAndData("成功", shareVo);
    }

    @Override
    public AjaxResult selectMerchantListByParentPhone(String phone) {
        List<ParentMerchantVo> list = merchantParentMapper.selectParentMerchantListByPhone(phone);
        return AjaxResult.successAndData("成功", list);
    }

    /**
     * 我的团队列表
     *
     * @param phone    手机号
     * @param pageNum  页数
     * @param pageSize 每页条数
     * @return
     */

    @Override
    public AjaxResult selectMerchantMyTeam(String phone, Integer pageNum, Integer pageSize) {
        if (StringUtils.isEmpty(phone) || pageNum == null || pageSize == null) {
            return AjaxResult.error(1, "参数缺少！");
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(phone);
        if (merchant == null) {
            return AjaxResult.error(1, "获取信息失败，请重试！");
        }
        Map<String, Object> map = new HashMap<>(16);
        //查询上级
        Merchant parMerchant = merchantMapper.selectByPhone(merchant.getParentPhone());
        if (StringUtils.isNotNull(parMerchant)) {
            map.put("parentPhone", parMerchant.getReservePhone());
        } else {
            map.put("parentPhone", "4008083305");
        }
        //商户姓名
        map.put("name", merchant.getMerchantCnName() == null ? merchant.getPhone() : merchant.getMerchantCnName());
        //注册时间
        map.put("createTime", merchant.getCreateTime());
        List<MyTeamVo> myTeamVoList = merchantMapper.selectMerchantListByCustomer(merchant.getPhone(), pageNum * pageSize, pageSize);
        if (myTeamVoList != null && myTeamVoList.size() > 0) {
            for (MyTeamVo teamVo : myTeamVoList) {
                //根据推荐人手机号查询直推总数
                Integer teamTotal1 = merchantParentMapper.selectMerchantBymerchantId(teamVo.getPhone());
                //新增人数:推荐人手机和当前日期查询
                String dateNow = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD);
                Integer dayAdditions = merchantMapper.selectAllTeamByParentphoneAndCreateDate(teamVo.getPhone(), dateNow);
                teamVo.setDayAdditions(dayAdditions);
                teamVo.setTeamCount(teamTotal1);
            }
        }
        map.put("directList", myTeamVoList);
        return AjaxResult.successAndData("成功", map);
    }

    @Override
    public AjaxResult myTeamTwo(String phone) {
        // TODO Auto-generated method stub
        if (StringUtils.isEmpty(phone)) {
            return AjaxResult.error(1, "参数缺少！");
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(phone);
        if (merchant == null) {
            return AjaxResult.error(1, "获取信息失败，请重试！");
        }
        MyTeamVo vo = new MyTeamVo();
        int vip = 0;
        int partner = 0;
        int newNum = 0;
        String dateNow = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD);
        List<MerchantParentVo> ml = merchantMapper.selectAllTeamByParentphone(merchant.getPhone());
        for (MerchantParentVo merchantParentVo : ml) {
            if (merchantParentVo.getLevel().equals(2)) {
                vip++;
            }
            if (merchantParentVo.getLevel().equals(6)) {
                partner++;
            }
            if (DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, merchantParentVo.getCreateTime()).equals(dateNow)) {
                newNum++;
            }
        }
        List<DayMonthVo> listday = merchantDayMapper.selectMerchantDayListByMerchantId(0, 1, merchant.getId());
        List<DayMonthVo> listmonth = merchantMonthMapper.selectMerchantMonthListByMerchantId(0, 1, merchant.getId());
        vo.setTeamCount(ml.size());
        vo.setVipTotal(vip);
        vo.setPartnerTotal(partner);
        vo.setDayAdditions(newNum);
        vo.setName(merchant.getMerchantCnName());
        vo.setLevel(merchant.getLevel().toString());
        vo.setPhone(merchant.getPhone());
        vo.setDay(listday);
        vo.setMonth(listmonth);
        return AjaxResult.successAndData("成功", vo);
    }

    /**
     * @param
     * @author fuzhili
     * @Description: 获取上次发送短信和当前时间的时间差
     * @date 2018/7/7 15:42安宁
     */
    @SuppressWarnings("unused")
    private Long geetweenSeconds(String startTime) {
        Date sendTime = DateTimeUtil.strToDate(startTime);
        // 判断发送时间和当前时间差
        Long seconds = DateTimeUtil.getBetweenSeconds(sendTime, new Date());
        return seconds;
    }

    /**
     * @param
     * @author fuzhili
     * @Description: 获取上次发送短信和当前时间的时间差
     * @date 2018/7/7 15:42
     */
    @SuppressWarnings("unused")
    private Long getBetweenSeconds(String startTime) {
        Date sendTime = DateTimeUtil.strToDate(startTime);
        // 判断发送时间和当前时间差
        Long seconds = DateTimeUtil.getBetweenSeconds(sendTime, new Date());
        return seconds;
    }

    /**
     * 客户关系 推荐数量
     *
     * @param phone
     * @return
     */
    @Override
    public List<Map<String, Object>> selectLevelsCount(String phone) {
        return merchantMapper.selectLevelsCount(phone);
    }


    @Override
    public AjaxResult vipPage(String merchantId) {
        String activityUpgrade = "";
        try {
            activityUpgrade = RedisPoolUtil.get("activityUpgrade");
        } catch (Exception e) {
            activityUpgrade = "nil";
        }
        if (activityUpgrade == null || "nil".equals(activityUpgrade) || "".equals(activityUpgrade)) {
            SystemConfig config = configMapper.selectSystemConfigByConfigCode("activityUpgrade");
            RedisPoolUtil.setex("activityUpgrade", config.getConfigValue(), 86400);
            activityUpgrade = config.getConfigValue();
        }
        JSONObject upgradeJson = JSONObject.parseObject(activityUpgrade);
        Map<String, Object> map = new HashMap<String, Object>();
        Merchant mer = merchantMapper.selectMerchantById(merchantId);
        map.put("merchant", mer);
        map.put("rateUrl", "https://five-g-huan.oss-cn-beijing.aliyuncs.com/five-g-huan/rate/rate.png");
        map.put("upgrade", upgradeJson.getString("activityUpgrade"));
        map.put("num", upgradeJson.getString("activityNum"));
        return AjaxResult.successAndData("成功", map);
    }

    /**
     * 商城积分兑换现金：支付密碼支付
     *
     * @param merchantId
     * @param productId
     * @param pwd
     * @return
     */
    @Override
    public AjaxResult shoppingExchangeCashByPwd(String merchantId, String productId, String pwd) {
        if (StringUtils.isEmpty(merchantId) || StringUtils.isEmpty(productId) || StringUtils.isEmpty(pwd)) {
            return AjaxResult.error(1, "缺失必要参数");
        }
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (merchant == null) {
            return AjaxResult.error(2, "用户信息不存在");
        }
        if (StringUtils.isEmpty(merchant.getPaymentPwd())) {
            return AjaxResult.error(2, "尚未设置支付密码，请先设置支付密码");
        }
        if (!StringUtils.equals(merchant.getPaymentPwd(), Md5Utils.encrypt2MD5(pwd))) {
            return AjaxResult.error(3, "支付密码不正确");
        }
        ShoppingProduct product = shoppingProductMapper.selectShoppingProductById(productId);
        if (product == null) {
            return AjaxResult.error(2, "商品信息不存在或已下架");
        }
        //todo 暂未有商城积分
        int shoppingScore = 0;
        int productScore = product.getShowScore() == null ? 0 : product.getShowScore();
        if (shoppingScore < productScore) {
            return AjaxResult.error(3, "积分不足");
        }
        //开始兑换现金  修改商户积分 添加新订单表，资金变动表

        String orderId = StringUtils.randomUUID();
        int r = 0;
        try {
            r = this.saveOrderByShoppingExchangeCash(product, merchant, orderId);
        } catch (Exception e) {
            logger.error(e.toString());
            return AjaxResult.error(1, "操作失败");
        }
        Map<String, String> map = new HashMap<>(4);
        map.put("orderId", orderId);
        if (r > 0) {
            return AjaxResult.successAndData("积分兑换成功", map);
        } else {
            return AjaxResult.error(3, "积分兑换失败,请联系客服人员");
        }

    }

    /**
     * 开始兑换现金  修改商户积分 添加新订单表，资金变动表
     *
     * @param product
     * @param merchant
     * @return
     */
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    protected int saveOrderByShoppingExchangeCash(ShoppingProduct product, Merchant merchant, String orderId) {

        return 0;
    }


    /**
     * 环信注册
     *
     * @param loginName 手机号
     * @return
     */
    @Override
    public AjaxResult createNewIMUserSingle(String loginName) {
        Merchant mer = merchantMapper.selectMerchantByPhone(loginName);
        if (StringUtils.isNull(mer)) {
            return AjaxResult.error(8, "该用户不存在！");
        }
        String passwords = "123456";
        try {
            TokenUtils.getAccessUsers(loginName, passwords);
        } catch (Exception e) {
            logger.error("环信{}", e);
            return AjaxResult.error(1, "");
        }
        return AjaxResult.successAndData("成功", "123456");
    }

    /**
     * 分享模块： 新注册/VIP/合伙人
     *
     * @param phone
     * @param type     :register新注册  ,vip VIP,partner 合伙人
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public AjaxResult selectMerchantMyTeamByType(String phone, String type, Integer pageNum, Integer pageSize) {
        if (StringUtils.isEmpty(phone) || pageNum == null || pageSize == null || StringUtils.isEmpty(type)) {
            return AjaxResult.error(1, "缺失必要参数");
        }
        Merchant merchant = merchantMapper.selectMerchantByPhone(phone);
        if (merchant == null) {
            return AjaxResult.error(1, "获取信息失败，请重试！");
        }
        Map<String, Object> map = new HashMap<>(16);
        //查询上级
        Merchant parMerchant = merchantMapper.selectByPhone(merchant.getParentPhone());
        if (StringUtils.isNotNull(parMerchant)) {
            map.put("parentPhone", parMerchant.getReservePhone());
        } else {
            map.put("parentPhone", "15612117289");
        }
        //商户姓名
        map.put("name", merchant.getMerchantCnName() == null ? merchant.getPhone() : merchant.getMerchantCnName());
        //注册时间
        map.put("createTime", merchant.getCreateTime());


        //type :register 新注册  ,vip VIP,partner 合伙人
        List<MyTeamVo> myTeamVoList = null;
        if ("vip".equals(type)) {
            myTeamVoList = merchantMapper.selectMerchantListByCustomerAndVip(merchant.getPhone(), pageNum * pageSize, pageSize);
        } else if ("partner".equals(type)) {
            myTeamVoList = merchantMapper.selectMerchantListByCustomerAndPartner(merchant.getPhone(), pageNum * pageSize, pageSize);
        } else if ("register".equals(type)) {
            myTeamVoList = merchantMapper.selectMerchantListByCustomerAndRegister(merchant.getPhone(), pageNum * pageSize, pageSize, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date()));

        } else {
            return AjaxResult.error(1, "暂无此查询类型！");
        }


        if ("vip".equals(type) || "partner".equals(type)) {
            if (myTeamVoList != null && myTeamVoList.size() > 0) {
                for (MyTeamVo teamVo : myTeamVoList) {
                    //根据推荐人手机号查询直推总数
                    Integer teamTotal1 = merchantParentMapper.selectMerchantBymerchantId(teamVo.getPhone());
                    //新增人数:推荐人手机和当前日期查询
                    String dateNow = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD);
                    Integer dayAdditions = merchantMapper.selectAllTeamByParentphoneAndCreateDate(teamVo.getPhone(), dateNow);
                    teamVo.setDayAdditions(dayAdditions);
                    teamVo.setTeamCount(teamTotal1);
                }
            }
        }

        map.put("directList", myTeamVoList);
        return AjaxResult.successAndData("成功", map);
    }


    /**
     * 修改上下级
     *
     * @param merchantPhone
     * @param parPhone
     * @return
     */
    @Override
    public int updateMerchantParent(String phone, String parPhone) {
        merchantMapper.updateParentPhoneByPhone(parPhone, phone);
        List<String> lowerPhones = merchantParentMapper.selectPhoneListByParentPhone(phone);
        lowerPhones.add(phone);
        merchantParentMapper.deleteMerchantParentByParentPhonOrPhone(phone);
        for (String lowerPhone : lowerPhones) {
            Merchant LowerMerchant = merchantMapper.selectByPhone(lowerPhone);
            String parentPhone = LowerMerchant.getParentPhone();
            int i = 1;
            while (true) {
                Merchant parentMerchant = merchantMapper.selectByPhone(parentPhone);
                if (parentMerchant == null) {
                    break;
                }
                MerchantParent merchantParent = new MerchantParent();
                merchantParent.setMerchantPhone(lowerPhone);
                merchantParent.setParentPhone(parentPhone);
                merchantParent.setIntervals(i);
                merchantParentMapper.insertMerchantParent(merchantParent);
                i++;
                parentPhone = parentMerchant.getParentPhone();
            }
        }
        return 1;
    }


    /**
     * DES敏感信息脱敏
     *
     * @return
     */
    private Merchant deDensity(Merchant mer) {
        if (mer != null) {
            //身份证号
            mer.setBankAccount(EncryptUtil.desEncryptMessage(mer.getBankAccount()));
            //银行卡号
            mer.setIdCardNumber(EncryptUtil.desEncryptMessage(mer.getIdCardNumber()));
        }
        return mer;
    }

    @Override
    public AjaxResult newChangesList(String phone, String day) {
        // TODO Auto-generated method stub
        List<MerchantParentVo> li = merchantMapper.selectNewTeamByParentphone(phone,
                day + " 00:00:00", day + " 23:59:59");
        return AjaxResult.successAndData("成功", li);
    }


    /********************************************人脸识别S***************************************************/


    /**
     * 获取token
     *
     * @return
     */
    public String token() {
        //获取token存放redis
        String keyPrefix = "config:";
        String accessToken = "";
        try {
            accessToken = RedisPoolUtil.get(keyPrefix + "accessToken");
        } catch (Exception e) {
            accessToken = "nil";
        }
        if (accessToken == null || "nil".equals(accessToken)) {
            String tokenS = HttpClientUtil.doPost(
                    "https://aip.baidubce.com/oauth/2.0/token"
                            + "?grant_type=client_credentials"
                            + "&client_id=1b0wR6QfoDG8ASGyhKvHmoQd"
                            + "&client_secret=oq3CC35lZ46fCaAbq5Ddds3X4GZ1nOoY");
            JSONObject jsonObject = JSONObject.parseObject(tokenS);
            accessToken = jsonObject.getString("access_token");
            RedisPoolUtil.setex(keyPrefix + "accessToken", accessToken, 60 * 60 * 24 * 15);
        }
        return accessToken;
    }


    /**
     * 对比手持是否本人
     *
     * @param url1 手持正面
     * @param url2 身份正面
     * @return
     */
    public String duibi(String url1, String url2) {
        String access_token = token();
        List<Map<String, String>> limap = new ArrayList<Map<String, String>>();
        Map<String, String> m1 = new HashMap<String, String>();
        m1.put("image", url1);//手持正面
        m1.put("image_type", "URL");
        m1.put("face_type", "LIVE");
        limap.add(m1);
        Map<String, String> m2 = new HashMap<String, String>();
        m2.put("image", url2);//身份正面
        m2.put("image_type", "URL");
        m2.put("face_type", "CERT");
        limap.add(m2);
        //m1.put("quality_control", value);
        System.out.println(JSONObject.toJSONString(limap));
        String a = HttpClientUtil.doPostJson("https://aip.baidubce.com/rest/2.0/face/v3/match"
                + "?access_token=" + access_token, JSONObject.toJSONString(limap));
        JSONObject jsonObject1 = JSONObject.parseObject(a);
        System.out.println("duibi-" + a);
        return jsonObject1.toJSONString();
    }


    /**
     * 身份识别
     *
     * @param imgUrlM
     * @return
     */
    public String shibi(String imgUrlM) {
        String access_token = token();
        Map<String, String> map = new HashMap<>();
        String base64 = ImageUtil.NetImageToBase64(imgUrlM);
        map.put("image", base64);
        map.put("id_card_side", "front");
        map.put("detect_direction", "false");
        String aaa = HttpClientUtil.doPost(
                "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
                        + "?access_token=" + access_token, map);
        JSONObject jsonObject1 = JSONObject.parseObject(aaa);
        return jsonObject1.toJSONString();
    }

    @Override
    public AjaxResult authenticationVt(String imgUrlM, String imgUrlE, Merchant merchant) {
        try {
            //对比手持是否本人
            String result = duibi(imgUrlM, imgUrlE);
            if (StringUtils.isEmpty(result)) {
                return AjaxResult.error("实名认证失败！如有疑问请联系客服咨询");
            }
            JSONObject resultJosn = JSONObject.parseObject(result);
            String errorMsg = resultJosn.getString("error_msg");
            String errorCode = resultJosn.getString("error_code");
            JSONObject resultduibi = resultJosn.getJSONObject("result");
            if (StringUtils.isNull(resultduibi)) {
                return AjaxResult.error("实名认证失败！请检查照片是否清晰");
            }
            System.out.println("resultduibi----" + resultduibi.toJSONString());
            if (("SUCCESS").equals(errorMsg)) {
                BigDecimal score = resultduibi.getBigDecimal("score");
                if (StringUtils.isNotNull(score)) {
                    //分低 就GG了
                    if ((score.setScale(0, BigDecimal.ROUND_DOWN)).doubleValue() < 25) {
                        logger.error("对比手持姓名-" + merchant.getMerchantCnName() + "分数-" + score);
                        return AjaxResult.error("请核实手持照片是否本人,如有疑问请联系客服咨询");
                    }
                }
            } else if (("216202").equals(errorCode) || ("222304").equals(errorCode)) {
                return AjaxResult.error("图片过大,请重新上传图片");
            } else if (("216201").equals(errorCode) || ("216633").equals(errorCode) || ("222202").equals(errorCode)) {
                return AjaxResult.error("请重新上传图片,如有疑问请联系客服咨询");
            } else {
                return AjaxResult.error("实名认证失败！如有疑问请联系客服咨询");
            }
            return AjaxResult.success("认证成功！");
        } catch (Exception e) {
            logger.error("app实名认证失败:{}", e);
            return AjaxResult.error("认证失败！如有疑问请联系客服咨询");
        }
    }


/*
    @Override
    public AjaxResult personVerify(String imgUrl, String merchantId, String name, String idCard) {
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (("10B").equals(merchant.getFreezeStatus())) {
            name = merchant.getMerchantCnName();
            idCard = merchant.getIdCardNumber();
        }
        try {
            String access_token = token();
            Map<String, String> map = new HashMap<>();
            map.put("image", imgUrl);
            map.put("liveness_control", "NONE");
            map.put("name", name);
            map.put("id_card_number", idCard);
            map.put("image_type", "URL");
            map.put("quality_control", "LOW");
            String url = "https://aip.baidubce.com/rest/2.0/face/v3/person/verify";
            String result = HttpClientUtil.doPost(url + "?access_token=" + access_token, map);
            System.out.println("身份检测-----" + result);
            //{"error_code":0,"error_msg":"SUCCESS","log_id":7975058965942,"timestamp":1581907981,"cached":0,"result":{"score":91.19639587}}

            JSONObject jsonObject1 = JSONObject.parseObject(result);
            String errorCode = jsonObject1.getString("error_code");
            if (!("0").equals(errorCode)) {
                return AjaxResult.error("认证失败！请核实是否本人,如有疑问请联系客服咨询");
            }
            JSONObject resultJson = jsonObject1.getJSONObject("result");
            Double score = resultJson.getDouble("score");
            if (score < 65) {
                logger.error("身份检测姓名-" + name + "分数-" + score);
                return AjaxResult.error("认证失败！请核实是否本人,如有疑问请联系客服咨询");
            }
            if (("10B").equals(merchant.getFreezeStatus())) {
                merchant.setFreezeStatus("10E");
                merchant.setExaminePassTime(new Date());
                merchantMapper.updateMerchant(merchant);
            }
            return AjaxResult.successAndData("认证成功！", merchant.getFreezeStatus());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("身份检测实名认证失败:{}", e);
            return AjaxResult.error("认证失败！请核实是否本人,如有疑问请联系客服咨询");
        }
    }
*/


    @Override
    public AjaxResult personVerify(String imgUrl, String merchantId, String name, String idCard) {
        Merchant merchant = merchantMapper.selectMerchantById(merchantId);
        if (("10B").equals(merchant.getRealNameStatus())) {
            merchant.setRealNameStatus("10E");
            merchant.setRealNameTime(new Date());
            merchantMapper.updateMerchant(merchant);
        }
        return AjaxResult.successAndData("认证成功！", merchant.getRealNameStatus());
    }

    /********************************************人脸识别E***************************************************/



}
